package gwtappcontainer.client;

import gwtappcontainer.client.apps.home.HomePresenterFactory;
import gwtappcontainer.client.apps.undefined.UndefinedPresenterFactory;
import gwtappcontainer.client.mydetails.MyDetailsPresenterFactory;
import gwtappcontainer.shared.LoginInfoProp;

import java.util.logging.Logger;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.user.client.History;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.RootLayoutPanel;

/**
 * Entry point classes define <code>onModuleLoad()</code>.
 */
public class GWTAppContainer implements EntryPoint {
	
	/**
	 * This is the entry point method.
	 */
	private Logger logger;
	private LoginInfoProp loginInfoProp;
	private ContainerPresenter containerPresenter;
						
	public void onModuleLoad() {
						
		logger = ContainerUtil.getLogger(GWTAppContainer.class.getName());
		
		ContainerView containerView = new ContainerView();
		containerPresenter = new ContainerPresenter(containerView);
		
		RootLayoutPanel.get().add(containerView);
		
		ContainerUtil.setBrowserWindowTitle(Constants.containerTitle);
		containerPresenter.setTitle(Constants.containerTitle);					
				
		LoginServiceAsync loginSvc = GWT.create(LoginService.class);			
		
		loginSvc.login(getRequesUrl(), new AsyncCallback<LoginInfoProp>() {

			@Override
			public void onFailure(Throwable caught) {
				String errMessage = "Exception thrown by login rpc." + caught.getMessage();
				logger.severe(errMessage + "\n" + caught.toString());			
				Window.alert(errMessage + 
						". Try reloading the page by clicking the refresh button in your browser");
				//to do : change to error dialog box
			}

			@Override
			public void onSuccess(LoginInfoProp result) {
				loginInfoProp = result;
				if (result.loggedIn) {
					containerPresenter.setUser(result.emailAddress);
					containerPresenter.setSignoutLink(result.logoutUrl);
				}							
				else {
					//containerPresenter.setUser("not logged in");
					containerPresenter.setSigninLink(loginInfoProp.loginUrl);							  
				}																					
			}					
		});	
		
		//add history listener
		History.addValueChangeHandler(new ValueChangeHandler<String>() {
			
			@Override
			public void onValueChange(ValueChangeEvent<String> event) {
				HistoryToken historyToken = new HistoryToken(event.getValue());
				IPresenterFactory presenterFactory = getPresenterFactory(historyToken.appName);
				
				IPresenter presenter = presenterFactory.get(historyToken);
				containerPresenter.renderApp(presenter);						
			}
		});
						
		//load home app
		HistoryToken historyToken = new HistoryToken(History.getToken());
		IPresenterFactory presenterFactory = getPresenterFactory(historyToken.appName);				
		
		IPresenter presenter = presenterFactory.get(historyToken);
		containerPresenter.renderApp(presenter);
	}	
	
	private String getRequesUrl() {
		String requestUrl = GWT.getHostPageBaseURL() + Window.Location.getQueryString();
		return requestUrl;
	}
	
	@SuppressWarnings("unused")
	private void testViewDesc() {
		//TODO - move to testing framework
		
		String hash;
		
		hash = "";
		Window.alert("hash = [" + hash + "] viewDesc " + ContainerUtil.getViewDesc_notused(hash));
		
		hash = "videos/view?tag=20130302";
		Window.alert("hash = [" + hash + "] viewDesc " + ContainerUtil.getViewDesc_notused(hash));
		
		hash = "videos/view?tag1=20130302&tag2=20120101&tag3=20110101&tag4=sowmya";
		Window.alert("hash = [" + hash + "] viewDesc " + ContainerUtil.getViewDesc_notused(hash));			
	}
	
	private IPresenterFactory getPresenterFactory(String appName) {
				
		if (appName.equals("")) appName = "home";
		
		appName = appName.toLowerCase();		
				
		if (appName.equals("home"))
			return new HomePresenterFactory();
		else if (appName.equals("mydetails"))
			return new MyDetailsPresenterFactory();	
		else
			return new UndefinedPresenterFactory();
		
			
//		//some reason code splitting doesn't seem to work properly
//		final PresenterFactoryHolder holder = new PresenterFactoryHolder();
//		if (appName.equals("home")) {
//			GWT.runAsync(new RunAsyncCallback() {
//				
//				@Override
//				public void onSuccess() {
//					holder.presenterFactory = new HomePresenterFactory();										
//				}
//				
//				@Override
//				public void onFailure(Throwable reason) {
//					Window.alert("!! Code split error.");					
//				}
//			});
//			return holder.presenterFactory;
//		}
//		
//		if (appName.equals("videos")) {
//			GWT.runAsync(new RunAsyncCallback() {
//				
//				@Override
//				public void onSuccess() {
//					holder.presenterFactory = new VideoPresenterFactory();										
//				}
//				
//				@Override
//				public void onFailure(Throwable reason) {
//					Window.alert("!! Code split error.");					
//				}
//			});
//			return holder.presenterFactory;
//		}
//		
//		GWT.runAsync(new RunAsyncCallback() {
//			
//			@Override
//			public void onSuccess() {
//				holder.presenterFactory = new UndefinedPresenterFactory();										
//			}
//			
//			@Override
//			public void onFailure(Throwable reason) {
//				Window.alert("!! Code split error.");					
//			}
//		});
//		return holder.presenterFactory;							
	}		
}
